package cc.sunni.activiti.controller;

import cc.sunni.activiti.pojo.UserInfoBean;
import cc.sunni.activiti.util.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.activiti.api.model.shared.model.VariableInstance;
import org.activiti.api.process.model.ProcessInstance;
import org.activiti.api.process.model.builders.ProcessPayloadBuilder;
import org.activiti.api.process.runtime.ProcessRuntime;
import org.activiti.api.runtime.shared.query.Page;
import org.activiti.api.runtime.shared.query.Pageable;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.ProcessDefinition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @author jl
 * @since 2021/1/29 19:36
 */
@Api(tags = "流程实例管理")
@RestController
@RequestMapping("/processInstance")
public class ProcessInstanceController {
    @Autowired
    private ProcessRuntime processRuntime;
    @Autowired
    private RepositoryService repositoryService;

    @GetMapping(value = "/list")
    @ApiOperation("获取流程实例列表")
    public R getInstances(@AuthenticationPrincipal UserInfoBean userInfoBean) {
        Page<ProcessInstance> processInstances = processRuntime.processInstances(Pageable.of(0, 50));
        List<ProcessInstance> list = processInstances.getContent();
        list.sort((y, x) -> x.getStartDate().toString().compareTo(y.getStartDate().toString()));

        List<HashMap<String, Object>> listMap = new ArrayList<>();
        for (ProcessInstance pi : list) {
            HashMap<String, Object> hashMap = new HashMap<>();
            hashMap.put("id", pi.getId());
            hashMap.put("name", pi.getName());
            hashMap.put("status", pi.getStatus());
            hashMap.put("processDefinitionId", pi.getProcessDefinitionId());
            hashMap.put("processDefinitionKey", pi.getProcessDefinitionKey());
            hashMap.put("startDate", pi.getStartDate());
            hashMap.put("processDefinitionVersion", pi.getProcessDefinitionVersion());
            //因为processRuntime.processDefinition("流程部署ID")查询的结果没有部署流程与部署ID，所以用repositoryService查询
            ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
                    .processDefinitionId(pi.getProcessDefinitionId())
                    .singleResult();
            hashMap.put("resourceName", pd.getResourceName());
            hashMap.put("deploymentId", pd.getDeploymentId());
            listMap.add(hashMap);
        }

        return R.ok(listMap);
    }

    @GetMapping(value = "/startProcess")
    @ApiOperation("启动流程")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "processDefinitionKey", value = "流程定义Key", required = true, dataTypeClass = String.class),
            @ApiImplicitParam(name = "instanceName", value = "自定义流程实例名称", required = true, dataTypeClass = String.class)})
    public R startProcess(@RequestParam("processDefinitionKey") String processDefinitionKey, @RequestParam("instanceName") String instanceName) {
        ProcessInstance processInstance = processRuntime.start(ProcessPayloadBuilder
                .start()
                .withProcessDefinitionKey(processDefinitionKey)
                .withName(instanceName)
                //.withVariable("k1", "v1")
                .withBusinessKey("自定义BusinessKey")
                .build());
        return R.ok(processInstance.getId());
    }

    @GetMapping(value = "/deleteInstance")
    @ApiOperation("删除流程")
    @ApiImplicitParam(name = "instanceId", value = "流程实例ID", required = true, dataTypeClass = String.class)
    public R deleteInstance(@RequestParam("instanceId") String instanceId) {
        processRuntime.delete(ProcessPayloadBuilder
                .delete()
                .withProcessInstanceId(instanceId)
                .build());
        return R.ok();
    }

    @GetMapping(value = "/suspendInstance")
    @ApiOperation("挂起流程")
    @ApiImplicitParam(name = "instanceId", value = "流程实例ID", required = true, dataTypeClass = String.class)
    public R suspendInstance(@RequestParam("instanceId") String instanceId) {
        processRuntime.suspend(ProcessPayloadBuilder
                .suspend()
                .withProcessInstanceId(instanceId)
                .build());
        return R.ok();
    }

    @GetMapping(value = "/resumeInstance")
    @ApiOperation("激活流程")
    @ApiImplicitParam(name = "instanceId", value = "流程实例ID", required = true, dataTypeClass = String.class)
    public R resumeInstance(@RequestParam("instanceId") String instanceId) {
        processRuntime.resume(ProcessPayloadBuilder
                .resume()
                .withProcessInstanceId(instanceId)
                .build());
        return R.ok();
    }

    @GetMapping(value = "/variables")
    @ApiOperation("查询流程参数")
    @ApiImplicitParam(name = "instanceId", value = "流程实例ID", required = true, dataTypeClass = String.class)
    public R variables(@RequestParam("instanceId") String instanceId) {
        List<VariableInstance> variableInstances = processRuntime.variables(ProcessPayloadBuilder
                .variables()
                .withProcessInstanceId(instanceId)
                .build());
        return R.ok(variableInstances);
    }
}
